<template>
    <view class="component-cate" :style="{ height: wrapHeight + 'px' }">
        <view class="menu-wrap">
            <scroll-view scroll-y class="tab-view menu-scroll-view" :scroll-top="scrollLeftTop" :enhanced="true" :bounces="false">
                <view
                    class="tab-item"
                    v-for="(item, index) in data"
                    :key="index"
                    :class="[currentLeftIndex == index ? 'tab-item-active' : '']"
                    @tap.stop="switchMenu(index)"
                >
                    <text class="line-1">{{ item.name }}</text>
                </view>
            </scroll-view>
            <scroll-view
                :scroll-top="scrollRightTop"
                scroll-y
                class="right-box"
                @scroll="rightScroll"
                :enhanced="true"
                :bounces="false"
            >
                <view class="page-view" :class="[cateType]">
                    <view
                        class="class-item"
                        v-for="(item, index) in data"
                        :key="index"
                        :style="{ minHeight: index == data.length - 1 ? wrapHeight - utils.rpx2px(36) + 'px' : 'auto' }"
                    >
                        <cate-tmpl v-if="cateType === 'cate'" :parentId="item.id" :data="item" @clickItem="clickItem"></cate-tmpl>
                        <list-tmpl
                            v-if="cateType === 'list'"
                            :parentId="item.id"
                            :data="item"
                            @clickItem="clickItem"
                            @changeNumber="changeNumber"
                        ></list-tmpl>
                    </view>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
import CateTmpl from "@/components/cate/template/cate";
import ListTmpl from "@/components/cate/template/list";
export default {
    name: "component-cate",
    data() {
        return {
            utils: this.$utils,
            isReady: false,

            leftNodePos: [],
            rightNodePos: [],
            queryTimer: null,
            currentLeftIndex: 0,
            wrapHeight: 0,
            scrollLeftTop: 0,
            scrollRightTop: 0,
            menuHeight: 0,
        };
    },
    props: {
        cateType: {
            type: String,
            default: "cate",
        },
        offsetHeight: {
            type: Number,
            default: 0,
        },
        activeId: {
            type: [String, Number],
            default: 0,
        },
        data: {
            type: Array,
            default: [],
        },
    },
    components: {
        CateTmpl,
        ListTmpl,
    },
    created() {},
    mounted() {
        const { windowHeight, statusBarHeight, headerHeight } = getApp().globalData.pageConfig;
        // 计算页面内边距------------------------------------------
        // #ifndef H5
        const bodyPt = statusBarHeight + headerHeight;
        // #endif
        // #ifdef H5
        const bodyPt = 0 + this.$utils.rpx2px(headerHeight * 2);
        // #endif
        // 计算页面内边距------------------------------------------
        const offsetHeight = this.$utils.rpx2px(this.offsetHeight);
        // 窗口高度 - 头部高度 - 顶部内容高度 = 分类容器高度
        this.wrapHeight = windowHeight - bodyPt - offsetHeight;
        // #ifdef H5
        // H5窗口高度会计算tabbar高度，这里减去
        this.wrapHeight -= this.$utils.rpx2px(100);
        // #endif

        this.menuHeight = this.$utils.rpx2px(100);
    },
    destroyed() {},
    watch: {
        /**
         * 监听列表数据变化
         */
        data() {
            this.init().then(() => {
                this.isReady = true;
                this.reAction();
            });
        },
        /**
         * 监听ID变化
         */
        activeId() {
            if (this.isReady) {
                this.reAction();
            }
        },
    },
    methods: {
        /**
         * 执行具体逻辑
         */
        reAction() {
            this.switchCate(this.activeId);
        },
        /**
         * 初始化列表
         */
        init() {
            clearTimeout(this.queryTimer);
            return new Promise((resolve, reject) => {
                const that = this;
                this.queryTimer = setTimeout(() => {
                    that.rightNodePos = [];
                    let query = uni.createSelectorQuery().in(that);
                    query
                        .selectAll(".class-item")
                        .boundingClientRect((result) => {
                            if (result.length > 0) {
                                result.forEach((item) => {
                                    that.rightNodePos.push(item.top - result[0].top);
                                });
                                resolve();
                            }
                        })
                        .exec();
                }, 200);
            });
        },
        /**
         * 更新左侧菜单
         */
        updateMenuStatus(index) {
            if (index != this.currentLeftIndex) {
                this.$emit("onScroll", this.data[index].id);
            }
            this.currentLeftIndex = index;
            this.scrollLeftTop = index * this.menuHeight - this.wrapHeight / 2;
        },
        /**
         * 滚动监听
         */
        rightScroll(e) {
            let scrollTop = e.detail.scrollTop + 15;
            for (let index = 0; index < this.rightNodePos.length; index++) {
                let current = this.rightNodePos[index];
                let next = this.rightNodePos[index + 1];
                if (!next || (scrollTop >= current && scrollTop < next)) {
                    this.updateMenuStatus(index);
                    return;
                }
            }
        },
        /**
         * 选中某项
         */
        switchMenu(index) {
            this.currentLeftIndex = index;
            this.scrollRightTop = this.rightNodePos[index];
        },
        /**
         * 按ID选中
         */
        switchCate(id) {
            let activeIndex = 0;
            this.data.forEach((item, index) => {
                if (item.id == id) {
                    activeIndex = index;
                }
            });
            this.switchMenu(activeIndex);
        },
        /**
         * 点击
         */
        clickItem(parentId, id) {
            this.$emit("clickItem", parentId, id);
        },
        /**
         * 改变数量
         */
        changeNumber(e, id) {
            this.$emit("changeNumber", e, id);
        },
    },
};
</script>

<style lang="less" scoped>
.component-cate {
    display: flex;
    flex-direction: column;
    width: 100%;
    .menu-wrap {
        flex: 1;
        display: flex;
        overflow: hidden;
    }
    .tab-view {
        width: 200rpx;
        height: 100%;
        background-color: #f6f6f6;
        .tab-item {
            height: 100rpx;
            box-sizing: border-box;
            padding-left: 20rpx;
            display: flex;
            align-items: center;
            font-size: 26rpx;
            font-weight: bold;
            color: #8b8b8b;
        }
        .tab-item-active {
            position: relative;
            color: #4b65ed;
            background: #ffffff;
        }
        .tab-item-active::before {
            content: "";
            position: absolute;
            border-left: 4px solid #4b65ed;
            height: 24rpx;
            left: 0;
            top: 38rpx;
        }
    }
    .right-box {
        width: 550rpx;
        .page-view.cate {
            padding-right: 16rpx;
        }
        .page-view.list {
            padding-right: 0;
        }
        .class-item {
            background-color: #ffffff;
            padding: 36rpx 32rpx 0 32rpx;
        }
        .class-item:last-child {
            padding-bottom: 36rpx;
        }
    }
}
</style>